from decimal import Decimal
from PySide6.QtWidgets import QVBoxLayout, QHBoxLayout, QWidget
from PySide6.QtCore import Qt
from PySide6.QtGui import QPainter, QFont, QColor
from PySide6.QtCharts import QChart, QChartView, QBarSeries, QBarSet, QBarCategoryAxis, QValueAxis, QStackedBarSeries
from .widgets.panels import BasePanel, CardPanel
from .widgets.basewidgets import ChartPushButton
from common import config
from api import api

CHAR_STRING_MAPPING = {
    "sales": "销售额",
    "purchase": "采购额",
    "sales_return": "退款额",
    "product": f"热销TOP{config.TOP_SALE_PRODUCT_COUNT}",
}

class DashboardPage(BasePanel):
    def __init__(self):
        super().__init__("控制台")
        self.current_chart_type = "sales"  # 'sales', 'purchase', 'sales_return', 'product'
        self.current_time_range = "week"   # 'year', 'month', 'week'
        self.statistics_data = None  # 存储API返回的数据
        self.setup_ui()
        self.setup_context_menu()
        
    def setup_ui(self):
        # 数据统计卡片
        cards_widget = QWidget()
        cards_layout = QHBoxLayout(cards_widget)
        
        # 商品总数卡片
        self.product_card = CardPanel(self, "商品总数(样)", "0", "低库存商品(样)", "0")
        cards_layout.addWidget(self.product_card)
        
        self.daily_sales_card = CardPanel(self, "日销售(单)", "0", f"日销售额({config.CURRENCY_UNIT})", "0")
        cards_layout.addWidget(self.daily_sales_card)

        self.monthly_sales_card = CardPanel(self, "月销售(单)", "0", f"月销售额({config.CURRENCY_UNIT})", "0")
        cards_layout.addWidget(self.monthly_sales_card)

        self.daily_sales_return_card = CardPanel(self, "日退款(单)", "0", f"日退款额({config.CURRENCY_UNIT})", "0")
        cards_layout.addWidget(self.daily_sales_return_card)

        self.monthly_sales_return_card = CardPanel(self, "月退款(单)", "0", f"月退款额({config.CURRENCY_UNIT})", "0")
        cards_layout.addWidget(self.monthly_sales_return_card)
        
        self.main_layout.addWidget(cards_widget)
        
        # 图表区域
        self.chart_area = QWidget()
        chart_layout = QVBoxLayout(self.chart_area)
        
        # 标签栏
        tabs_widget = QWidget()
        tabs_layout = QHBoxLayout(tabs_widget)
        tabs_layout.setContentsMargins(0, 0, 0, 0)
        
        # 创建数据类型切换按钮
        self.sales_btn = ChartPushButton(CHAR_STRING_MAPPING["sales"])
        self.sales_btn.setChecked(True)
        self.sales_btn.setObjectName("noneBorder1")
        self.sales_btn.clicked.connect(lambda: self.change_chart_type("sales"))
        
        self.purchase_btn = ChartPushButton(CHAR_STRING_MAPPING["purchase"])
        self.purchase_btn.setObjectName("noneBorder1")
        self.purchase_btn.clicked.connect(lambda: self.change_chart_type("purchase"))
        
        self.sales_return_btn = ChartPushButton(CHAR_STRING_MAPPING["sales_return"])
        self.sales_return_btn.setObjectName("noneBorder1")
        self.sales_return_btn.clicked.connect(lambda: self.change_chart_type("sales_return"))

        self.hot_product_btn = ChartPushButton(CHAR_STRING_MAPPING["product"])
        self.hot_product_btn.setObjectName("noneBorder1")
        self.hot_product_btn.clicked.connect(lambda: self.change_chart_type("product"))
        
        tabs_layout.addWidget(self.sales_btn)
        tabs_layout.addWidget(self.purchase_btn)
        tabs_layout.addWidget(self.sales_return_btn)
        tabs_layout.addWidget(self.hot_product_btn)
        tabs_layout.addStretch()
        
        # 时间过滤器
        period_widget = QWidget()
        period_layout = QHBoxLayout(period_widget)
        
        self.year_btn = ChartPushButton("今年")
        self.year_btn.setObjectName("noneBorder2")
        self.year_btn.clicked.connect(lambda: self.change_time_range("year"))
        
        self.month_btn = ChartPushButton("本月")
        self.month_btn.setObjectName("noneBorder2")
        self.month_btn.clicked.connect(lambda: self.change_time_range("month"))
        
        self.week_btn = ChartPushButton("本周")
        self.week_btn.setChecked(True)
        self.week_btn.setObjectName("noneBorder2")
        self.week_btn.clicked.connect(lambda: self.change_time_range("week"))
        
        period_layout.addWidget(self.year_btn)
        period_layout.addWidget(self.month_btn)
        period_layout.addWidget(self.week_btn)
        
        tabs_layout.addWidget(period_widget)
        chart_layout.addWidget(tabs_widget)
        
        # 创建图表容器
        self.chart_container = QWidget()
        self.chart_container_layout = QVBoxLayout(self.chart_container)
        self.chart_container_layout.setContentsMargins(0, 0, 0, 0)
        
        chart_layout.addWidget(self.chart_container)
        self.main_layout.addWidget(self.chart_area)
    
    def change_chart_type(self, chart_type):
        self.current_chart_type = chart_type
        
        # 更新按钮样式
        self.sales_btn.setChecked(chart_type == "sales")
        self.purchase_btn.setChecked(chart_type == "purchase")
        self.sales_return_btn.setChecked(chart_type == "sales_return")
        self.hot_product_btn.setChecked(chart_type == "product")
        
        # 更新图表
        self.update_chart()
    
    def change_time_range(self, time_range):
        self.current_time_range = time_range
        
        self.year_btn.setChecked(time_range == "year")
        self.month_btn.setChecked(time_range == "month")
        self.week_btn.setChecked(time_range == "week")
        
        # 更新图表
        self.update_chart()
    
    def update_chart(self):
        # 清除现有图表
        for i in reversed(range(self.chart_container_layout.count())): 
            self.chart_container_layout.itemAt(i).widget().setParent(None)
        
        # 根据当前选择的类型和时间范围创建图表
        chart_view = self.create_chart(self.current_chart_type, self.current_time_range)
        self.chart_container_layout.addWidget(chart_view)
    
    def create_chart(self, chart_type, time_range):
        # 设置图表颜色
        chart_colors = {
            "sales": QColor("#1a75ff"),     # 蓝色
            "purchase": QColor("#28a745"),  # 绿色
            "sales_return": QColor("#fd7e14"),      # 橙色
            "product_sales": QColor("#1a75ff"),  # 蓝色（销售额）
            "product_profit": QColor("#28a745"),  # 绿色（利润额）
        }
        
        label_colors = {
            "sales": QColor("#003380"),     # 深蓝色
            "purchase": QColor("#115522"),  # 深绿色
            "sales_return": QColor("#994400"),      # 深橙色
            "product_sales": QColor("#003380"),  # 深蓝色（销售额）
            "product_profit": QColor("#115522"),  # 深绿色（利润额）
        }
        

        # 根据图表类型和时间范围获取数据
        data, categories, max_value = self.get_chart_data(chart_type, time_range)
        if chart_type == "product":
            series = QStackedBarSeries()
            sales_set = QBarSet("销售额")
            profit_set = QBarSet("利润额")
            for item in data:
                sales_set.append(item[0])
                profit_set.append(item[1])
            sales_set.setColor(chart_colors["product_sales"])
            sales_set.setBorderColor(chart_colors["product_sales"].darker(120))
            sales_set.setLabelColor(label_colors["product_sales"])
            profit_set.setColor(chart_colors["product_profit"])
            profit_set.setBorderColor(chart_colors["product_profit"].darker(120))
            profit_set.setLabelColor(label_colors["product_profit"])
            series.append(sales_set)
            series.append(profit_set)
        else:
            series = QBarSeries()
            bar_set = QBarSet(self.get_chart_title(chart_type))
            bar_set.setColor(chart_colors[chart_type])
            bar_set.setBorderColor(chart_colors[chart_type].darker(120))
            bar_set.setLabelColor(label_colors[chart_type])
            bar_set.append(data)
            series.append(bar_set)
        
        # 设置显示数值标签
        series.setLabelsVisible(True)
        # 设置数值标签位置在柱形顶部
        series.setLabelsPosition(QBarSeries.LabelsPosition.LabelsOutsideEnd)
        
        # 设置标签字体
        label_font = QFont()
        label_font.setBold(True)
        label_font.setPointSize(10)
        
        # 创建图表
        chart = QChart()
        chart.addSeries(series)
        chart.setAnimationOptions(QChart.SeriesAnimations)
        chart.setTitle("")
        chart.setBackgroundVisible(False)
        
        # 设置X轴
        axis_x = QBarCategoryAxis()
        axis_x.append(categories)
        chart.addAxis(axis_x, Qt.AlignBottom)
        series.attachAxis(axis_x)
        if len(categories) > config.AXIS_X_MAX_TICKS:
            axis_x.setLabelsAngle(90)
        
        # 设置Y轴
        axis_y = QValueAxis()
        axis_y.setRange(0, max_value * Decimal(1.2))  # 增加20%的空间，留给标签显示
        axis_y.setTickCount(7)
        
        # 设置Y轴字体颜色
        axis_y.setLabelsColor(QColor("#333333"))
        
        # 为Y轴添加千位分隔符格式（金额类型图表）
        if chart_type == "sales" or chart_type == "purchase":
            axis_y.setLabelFormat("%'.0f")  # 使用千位分隔符，不显示小数点
        
        chart.addAxis(axis_y, Qt.AlignLeft)
        series.attachAxis(axis_y)
        
        # 设置X轴字体颜色
        axis_x.setLabelsColor(QColor("#333333"))
        
        # 图例
        chart.legend().setVisible(True)
        chart.legend().setAlignment(Qt.AlignBottom)
        
        # 创建视图
        chart_view = QChartView(chart)
        chart_view.setRenderHint(QPainter.RenderHint.Antialiasing)
        
        return chart_view
    
    def get_chart_title(self, chart_type):
        return CHAR_STRING_MAPPING.get(chart_type, "")
    
    def get_chart_data(self, chart_type, time_range):
        # 根据不同的图表类型和时间范围返回对应的数据
        data = []
        categories = []
        max_value = Decimal(1)
        # 根据时间范围选择对应的数据和类别
        if chart_type == "sales":
            data_list = api.get_sales_chart_data(time_range)
        elif chart_type == "purchase":
            data_list = api.get_purchases_chart_data(time_range)
        elif chart_type == "sales_return":
            data_list = api.get_sales_return_chart_data(time_range)
        elif chart_type == "product":
            data_list = api.get_hot_products_chart_data(time_range)
        else:
            return [], [], 1
        
        # 遍历API返回的数据列表
        for item in data_list:
            # 每个item是一个字典，只有一个键值对
            for key, value in item.items():
                categories.append(key)
                data.append(value)
                max_value = max(max_value, value if isinstance(value, (int, float, Decimal)) else value[0])
        return data, categories, max_value

    def load_data(self):        
        # 获取API数据
        self.statistics_data = api.get_home_statistics()
        
        # 更新卡片数据
        self.product_card.update_value(self.statistics_data["total_products"], self.statistics_data["low_stock_products"])
        self.daily_sales_card.update_value(self.statistics_data["daily_sales"], self.statistics_data["daily_sales_prices"])
        self.monthly_sales_card.update_value(self.statistics_data["monthly_sales"], self.statistics_data["monthly_sales_prices"])
        self.daily_sales_return_card.update_value(self.statistics_data["daily_sales_return"], self.statistics_data["daily_sales_prices_return"])
        self.monthly_sales_return_card.update_value(self.statistics_data["monthly_sales_return"], self.statistics_data["monthly_sales_prices_return"])
        
        # 更新图表
        self.update_chart()